import { NextSeo } from 'next-seo';

<NextSeo description="Configure your application with the serverless.yml file." />

# serverless.yml

Your application is deployed using the Serverless framework based on the `serverless.yml` configuration file.

This page introduces a few advanced concepts of the `serverless.yml` format. You can learn more in the [official Serverless documentation](https://serverless.com/framework/docs/providers/aws/).

## Overview

```yml filename="serverless.yml"
service: app

provider:
    name: aws

plugins:
    - ./vendor/bref/bref

functions:
    foo:
        handler: index.php
        runtime: php-81

resources:
    Resources:
        MyBucket:
            Type: AWS::S3::Bucket
            Properties:
                BucketName: 'my-bucket'
```

## Service

```yml
service: app
```

The [service](https://serverless.com/framework/docs/providers/aws/guide/services/) is simply the name of your project.

Since Serverless lets us deploy a project in [multiple stages](../deploy.mdx#stages) (prod, dev, staging…), CloudFormation stacks will contain both the service name and the stage: `app-prod`, `app-dev`, etc.

## Provider

```yml
provider:
    name: aws
```

Bref only supports the `aws` provider, even though Serverless can deploy applications on other cloud providers like Google Cloud, Azure, etc.

```yml
provider:
    name: aws
    # The AWS region in which to deploy (us-east-1 by default)
    region: us-east-1
    # The stage of the application, e.g. dev, prod, staging… ('dev' by default)
    stage: dev
```

The `provider` section also lets us configure global options on all functions:

```yaml
provider:
    name: aws
    runtime: php-81
    timeout: 10

functions:
    foo:
        handler: foo.php
    bar:
        handler: bar.php

# ...
```

is the same as:

```yaml
provider:
    name: aws

functions:
    foo:
        handler: foo.php
        runtime: php-81
        timeout: 10
    bar:
        handler: bar.php
        runtime: php-81
        timeout: 10

# ...
```

## Plugins

```yaml
plugins:
    - ./vendor/bref/bref
```

[Serverless plugins](https://serverless.com/framework/docs/providers/aws/guide/plugins/) are JavaScript plugins that extend the behavior of the Serverless framework.

Bref provides a plugin via the Composer package, which explains why the path is a relative path into the `vendor` directory. This plugin provides [support for the Bref runtimes and layers](../runtimes/#usage), it is necessary to include it.

Most other Serverless plugins [are installed via `npm`](https://serverless.com/framework/docs/providers/aws/guide/plugins/).

You can find the list of [all Serverless plugins here](https://serverless.com/plugins/).

## Exclusions

It is possible to exclude directories from being deployed via the `package.patterns` section:

```yaml
package:
    patterns:
        - '!node_modules/**'
        - '!tests/**'
```

This has the following benefits:

- faster deployments
- less risk of hitting [Lambda's size limit](https://docs.aws.amazon.com/lambda/latest/dg/limits.html)
- [faster cold starts](performances.md)

Read more about the `package` configuration [in the serverless.yml documentation](https://www.serverless.com/framework/docs/providers/aws/guide/packaging#patterns).

## Functions

```yaml
functions:
    foo:
        handler: foo.php
        runtime: php-81
    bar:
        handler: bar.php
        runtime: php-81
```

Functions are AWS Lambda functions. You can find all options available [in this Serverless documentation page](https://serverless.com/framework/docs/providers/aws/guide/functions/).

Note that it is possible to mix PHP functions with functions written in other languages in the same `serverless.yml` config.

### Permissions

If your lambda needs to access other AWS services (S3, SQS, SNS…), you will need to add the proper permissions via the `iam.role.statements` section.

Read more about [AWS credentials in the documentation](./aws-credentials.mdx).

## Stage parameters

Stage parameters are a great way to define values that change depending on the stage (dev, prod, staging…).

```yaml
params:
    # Default parameters that apply to all stages
    default:
        # Here we use the special `sls:stage` variable
        # to define a domain that changes depending on the stage
        domain: ${sls:stage}.preview.myapp.com
    # Parameters that apply to the prod stage
    prod:
        domain: myapp.com
    # Parameters that apply to the dev stage
    dev:
        domain: preview.myapp.com

# Parameters can be used via the ${param:XXX} variables:
provider:
    environment:
        APP_DOMAIN: ${param:domain}
```

Read the full [Serverless documentation about stage parameters](https://github.com/serverless/serverless/blob/v3/docs/guides/dashboard/parameters.md#stage-parameters).

## Resources

```yaml
resources:
    Resources:
        MyBucket:
            Type: AWS::S3::Bucket
            Properties:
                BucketName: 'my-bucket'
```

The `resources` section contains raw [CloudFormation syntax](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-reference.html). This lets us define any kind of AWS resource other than Lambda functions.

Read more in the [Serverless documentation about resources](https://serverless.com/framework/docs/providers/aws/guide/resources/).

Be careful, the CloudFormation resources must be defined in the `resources.Resources` sub-section:

```yaml
resources:
    Resources:
        # ...
```

### CloudFormation functions

The CloudFormation `!Ref`, `!GetAtt` and `!Sub` functions can be used.

Here is an example where we define a S3 bucket and a policy that references it. It uses both the `!Ref MyBucket` and `!Sub '${MyBucket.Arn}'` syntaxes:

```yml filename="serverless.yml"
#...

resources:
    Resources:
        MyBucket:
            Type: AWS::S3::Bucket
        # IAM policy that makes the bucket publicly readable
        MyBucketPolicy:
            Type: AWS::S3::BucketPolicy
            Properties:
                Bucket: !Ref MyBucket
                PolicyDocument:
                    Statement:
                        -   Effect: Allow
                            Principal: '*' # everyone
                            Action: s3:GetObject
                            Resource: !Sub '${MyBucket.Arn}/*'
```
